package wwk.common.util;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import java.io.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

import android.util.Log;
import java.io.File;

public class ZipUtil
{
	private static final String TAG="ZipUtil";
	
    private static final int BUFF_SIZE = 1024 * 1024; // 1M Byte
    
	/**
	 * ��ѹ������,ֻ��ѹ��һ���ļ�
	 * @param zipInputStream
	 * @param fileNameInZip
	 * @param destFilePathName
	 */
	static public boolean unZip(InputStream zipInputStream,String fileNameInZip,String destFilePathName)
	{
		boolean ret = false;

		try
		{
			// ������Ŀ���ļ�����������
			ZipInputStream in = new ZipInputStream(zipInputStream);
			ZipEntry file = in.getNextEntry();

			byte[] buffer = new byte[1024];
			int slen;

			int i = 0;
			boolean unzip = false;
			while (file != null)
			{
				if (fileNameInZip == null)
				{
					if (i == 0)
					{
						unzip = true;
					}
				}
				else
				{
					if (fileNameInZip.equalsIgnoreCase(file.getName()))
					{
						unzip = true;
					}
				}

				if (unzip)
				{
					FileUtil.delete(destFilePathName);
					FileUtil.createFile(destFilePathName);

					// ��ɽ�ѹ����ļ�
					FileOutputStream out = new FileOutputStream(
							destFilePathName);
					while ((slen = in.read(buffer, 0, buffer.length)) != -1)
					{
						out.write(buffer, 0, slen);
					}
					out.close();
					
					ret=true;
					break;
				}

				System.out.print("O.K. ");
				file = in.getNextEntry();
				i++;
			}

			in.close();
		}
		catch (ZipException zipe)
		{
			Log.e(TAG, zipe.toString());
		}
		catch (IOException ioe)
		{
			Log.e(TAG, ioe.toString());
		}
		catch (Exception e)
		{
			Log.e(TAG, e.toString());
		}
		
		return ret;
	}
	
//	/**
//	 * ��ѹzip�ļ���
//	 * @param zipFilePathName
//	 */
//	static public void unZip(String zipFilePathName)
//	{
//		  File infile = new File(zipFilePathName);
//
//		  try
//		  {
//			   //����Ƿ���ZIP�ļ�
//			   ZipFile zip = new ZipFile(infile);
//			   zip.close();
//			   
//			   //������Ŀ���ļ�����������
//			   ZipInputStream in = new ZipInputStream(new FileInputStream(infile));
//			   ZipEntry file = in.getNextEntry();
//			   
//			   //����һ��Ŀ¼
//			   int i =infile.getAbsolutePath().lastIndexOf('.');
//			   String dirname = new String();
//			   if ( i != -1 )
//				   dirname = infile.getAbsolutePath().substring(0,i);
//			   else
//				   dirname = infile.getAbsolutePath();
//			   File newdir = new File(dirname);
//			   newdir.mkdir();
//			   
//			   byte[] c = new byte[1024];
//			   int slen;
//		   
//			   while (file != null)
//			   {
//				    i = file.getName().lastIndexOf('/');
//				    if ( i != -1 )
//				    {
//					     File dirs = new File(dirname+File.separator+file.getName().substring(0,i));
//					     dirs.mkdirs();
//					     dirs = null;
//				    }
//			    
//				    System.out.print("Extract "+file.getName());
//			    
//				    if (file.isDirectory())
//				    {
//					     File dirs = new File(file.getName());
//					     dirs.mkdir();
//					     dirs = null;
//				    }
//				    else
//				    { 
//				    	//��ɽ�ѹ����ļ�
//					     FileOutputStream out = new FileOutputStream(dirname+File.separator+file.getName());
//					     while((slen = in.read(c,0,c.length)) != -1)
//					    	 out.write(c,0,slen);
//					     out.close();
//				    }
//				    System.out.print("O.K. ");
//				    file = in.getNextEntry();
//			   }
//			   
//			   in.close();
//		  }
//		  catch(ZipException zipe)
//		  {
//			  //MessageBox(0,infile.getName()+"����һ��ZIP�ļ���","�ļ���ʽ����",16);
//			  Log.d("",zipe.toString());
//		  }
//		  catch(IOException ioe)
//		  {
//			  //MessageBox(0,"��ȡ"+args[0]+"ʱ����","�ļ���ȡ����",16);
//			  Log.d("",ioe.toString());
//		  }
//		  catch(Exception e)
//		  {
//			  Log.d("",e.toString());
//			  System.out.println("over");
//		  }
//	}

    /**
     * ����ѹ���ļ����У�
     *
     * @param resFileList Ҫѹ�����ļ����У��б�
     * @param zipFile ��ɵ�ѹ���ļ�
     * @throws IOException ��ѹ����̳���ʱ�׳�
     */
    public static void zipFiles(Collection<File> resFileList, File zipFile) throws IOException {
        ZipOutputStream zipout = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(
                zipFile), BUFF_SIZE));
        for (File resFile : resFileList) {
            zipFile(resFile, zipout, "");
        }
        zipout.close();
    }

    /**
     * ����ѹ���ļ����У�
     *
     * @param resFileList Ҫѹ�����ļ����У��б�
     * @param zipFile ��ɵ�ѹ���ļ�
     * @param comment ѹ���ļ���ע��
     * @throws IOException ��ѹ����̳���ʱ�׳�
     */
    public static void zipFiles(Collection<File> resFileList, File zipFile, String comment)
            throws IOException {
        ZipOutputStream zipout = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(
                zipFile), BUFF_SIZE));
        for (File resFile : resFileList) {
            zipFile(resFile, zipout, "");
        }
        zipout.setComment(comment);
        zipout.close();
    }

    /**
     * ��ѹ��һ���ļ�
     *
     * @param zipFile ѹ���ļ�
     * @param folderPath ��ѹ����Ŀ��Ŀ¼
     * @throws IOException ����ѹ����̳���ʱ�׳�
     */
    public static void unZipFile(File zipFile, String folderPath) throws ZipException, IOException {
        File desDir = new File(folderPath);
        if (!desDir.exists()) {
            desDir.mkdirs();
        }
        ZipFile zf = new ZipFile(zipFile);
        for (Enumeration<?> entries = zf.entries(); entries.hasMoreElements();) {
            ZipEntry entry = ((ZipEntry)entries.nextElement());
            InputStream in = zf.getInputStream(entry);
            String str = folderPath + File.separator + entry.getName();
            str = new String(str.getBytes("8859_1"), "GB2312");
            File desFile = new File(str);
            if (!desFile.exists()) {
                File fileParentDir = desFile.getParentFile();
                if (!fileParentDir.exists()) {
                    fileParentDir.mkdirs();
                }
                desFile.createNewFile();
            }
            OutputStream out = new FileOutputStream(desFile);
            byte buffer[] = new byte[BUFF_SIZE];
            int realLength;
            while ((realLength = in.read(buffer)) > 0) {
                out.write(buffer, 0, realLength);
            }
            in.close();
            out.close();
        }
    }

    /**
     * ��ѹ�ļ���������ֵ��ļ�
     *
     * @param zipFile ѹ���ļ�
     * @param folderPath Ŀ���ļ���
     * @param nameContains ������ļ�ƥ����
     * @throws ZipException ѹ����ʽ����ʱ�׳�
     * @throws IOException IO����ʱ�׳�
     */
    public static ArrayList<File> unZipSelectedFile(File zipFile, String folderPath,
            String nameContains) throws ZipException, IOException {
        ArrayList<File> fileList = new ArrayList<File>();

        File desDir = new File(folderPath);
        if (!desDir.exists()) {
            desDir.mkdir();
        }

        ZipFile zf = new ZipFile(zipFile);
        for (Enumeration<?> entries = zf.entries(); entries.hasMoreElements();) {
            ZipEntry entry = ((ZipEntry)entries.nextElement());
            if (entry.getName().contains(nameContains)) {
                InputStream in = zf.getInputStream(entry);
                String str = folderPath + File.separator + entry.getName();
                str = new String(str.getBytes("8859_1"), "GB2312");
                // str.getBytes("GB2312"),"8859_1" ���
                // str.getBytes("8859_1"),"GB2312" ����
                File desFile = new File(str);
                if (!desFile.exists()) {
                    File fileParentDir = desFile.getParentFile();
                    if (!fileParentDir.exists()) {
                        fileParentDir.mkdirs();
                    }
                    desFile.createNewFile();
                }
                OutputStream out = new FileOutputStream(desFile);
                byte buffer[] = new byte[BUFF_SIZE];
                int realLength;
                while ((realLength = in.read(buffer)) > 0) {
                    out.write(buffer, 0, realLength);
                }
                in.close();
                out.close();
                fileList.add(desFile);
            }
        }
        return fileList;
    }

    /**
     * ���ѹ���ļ����ļ��б�
     *
     * @param zipFile ѹ���ļ�
     * @return ѹ���ļ����ļ����
     * @throws ZipException ѹ���ļ���ʽ����ʱ�׳�
     * @throws IOException ����ѹ����̳���ʱ�׳�
     */
    public static ArrayList<String> getEntriesNames(File zipFile) throws ZipException, IOException {
        ArrayList<String> entryNames = new ArrayList<String>();
        Enumeration<?> entries = getEntriesEnumeration(zipFile);
        while (entries.hasMoreElements()) {
            ZipEntry entry = ((ZipEntry)entries.nextElement());
            entryNames.add(new String(getEntryName(entry).getBytes("GB2312"), "8859_1"));
        }
        return entryNames;
    }

    /**
     * ���ѹ���ļ���ѹ���ļ�������ȡ��������
     *
     * @param zipFile ѹ���ļ�
     * @return ����һ��ѹ���ļ��б�
     * @throws ZipException ѹ���ļ���ʽ����ʱ�׳�
     * @throws IOException IO��������ʱ�׳�
     */
    public static Enumeration<?> getEntriesEnumeration(File zipFile) throws ZipException,
            IOException {
        ZipFile zf = new ZipFile(zipFile);
        return zf.entries();

    }

    /**
     * ȡ��ѹ���ļ������ע��
     *
     * @param entry ѹ���ļ�����
     * @return ѹ���ļ������ע��
     * @throws UnsupportedEncodingException
     */
    public static String getEntryComment(ZipEntry entry) throws UnsupportedEncodingException {
        return new String(entry.getComment().getBytes("GB2312"), "8859_1");
    }

    /**
     * ȡ��ѹ���ļ���������
     *
     * @param entry ѹ���ļ�����
     * @return ѹ���ļ���������
     * @throws UnsupportedEncodingException
     */
    public static String getEntryName(ZipEntry entry) throws UnsupportedEncodingException {
        return new String(entry.getName().getBytes("GB2312"), "8859_1");
    }

    /**
     * ѹ���ļ�
     *
     * @param resFile ��Ҫѹ�����ļ����У�
     * @param zipout ѹ����Ŀ���ļ�
     * @param rootpath ѹ�����ļ�·��
     * @throws FileNotFoundException �Ҳ����ļ�ʱ�׳�
     * @throws IOException ��ѹ����̳���ʱ�׳�
     */
    private static void zipFile(File resFile, ZipOutputStream zipout, String rootpath)
            throws FileNotFoundException, IOException {
        rootpath = rootpath + (rootpath.trim().length() == 0 ? "" : File.separator)
                + resFile.getName();
        rootpath = new String(rootpath.getBytes("8859_1"), "GB2312");
        if (resFile.isDirectory()) {
            File[] fileList = resFile.listFiles();
            for (File file : fileList) {
                zipFile(file, zipout, rootpath);
            }
        } else {
            byte buffer[] = new byte[BUFF_SIZE];
            BufferedInputStream in = new BufferedInputStream(new FileInputStream(resFile),
                    BUFF_SIZE);
            zipout.putNextEntry(new ZipEntry(rootpath));
            int realLength;
            while ((realLength = in.read(buffer)) != -1) {
                zipout.write(buffer, 0, realLength);
            }
            in.close();
            zipout.flush();
            zipout.closeEntry();
        }
    }
}
